//! gRPC服务器实现
//! 
//! 实现SandboxManagerService的gRPC服务端，与现有的沙箱管理系统集成

use std::sync::Arc;
use std::collections::HashMap;
use tonic::{Request, Response, Status};
use tracing::{info, error, warn};
use chrono::Utc;

use crate::sandbox_manager::SandboxManager;
use crate::types::{SandboxId, Language as CoreLanguage, Priority as CorePriority};
use crate::grpc::proto::{
    sandbox_manager_service_server::SandboxManagerService,
    SandboxRequest, SandboxInfo, ExecutionRequest, ExecutionResult,
    ReleaseSandboxRequest, ReleaseResponse, SandboxStatusRequest, SandboxStatus,
    SystemStatsRequest, SystemStats, HealthCheckRequest, HealthCheckResponse,
    Language, Priority, SandboxState, HealthLevel, HealthStatus,
    ResourceRequirements, PoolStats, PoolInfo, ResourceUsage,
};

/// gRPC服务器实现
pub struct SandboxManagerServer {
    sandbox_manager: Arc<SandboxManager>,
}

impl SandboxManagerServer {
    /// 创建新的gRPC服务器实例
    pub fn new(sandbox_manager: Arc<SandboxManager>) -> Self {
        Self {
            sandbox_manager,
        }
    }
}

#[tonic::async_trait]
impl SandboxManagerService for SandboxManagerServer {
    /// 分配沙箱
    async fn allocate_sandbox(
        &self,
        request: Request<SandboxRequest>,
    ) -> Result<Response<SandboxInfo>, Status> {
        let req = request.into_inner();
        info!("收到沙箱分配请求: language={:?}, priority={:?}", 
              req.language, req.priority);

        // 转换语言类型
        let language = match Language::try_from(req.language) {
            Ok(lang) => convert_language_to_core(lang),
            Err(_) => {
                return Err(Status::invalid_argument("不支持的编程语言"));
            }
        };

        // 转换优先级
        let priority = match Priority::try_from(req.priority) {
            Ok(prio) => convert_priority_to_core(prio),
            Err(_) => {
                return Err(Status::invalid_argument("无效的优先级"));
            }
        };

        // 构建资源需求
        let resource_req = req.resources.unwrap_or_default();
        let resources = crate::types::ResourceRequirements {
            memory_mb: resource_req.memory_mb,
            cpu_cores: resource_req.cpu_cores,
            disk_mb: resource_req.disk_mb,
            network_enabled: resource_req.network_enabled,
            network_bandwidth_mbps: 100, // 默认100Mbps，因为proto中没有此字段
        };

        // 分配沙箱 (目前实现为创建沙箱)
        let spec = crate::types::SandboxSpec {
            cpu_cores: resources.cpu_cores,
            memory_mb: resources.memory_mb as u64,
            disk_mb: resources.disk_mb as u64,
            network_enabled: resources.network_enabled,
            timeout_secs: req.timeout_seconds as u64,
            language,
            env_vars: std::collections::HashMap::new(),
            snapshot_path: None,
            memory_file_path: None,
            kernel_image_path: None,
            rootfs_path: None,
        };

        match self.sandbox_manager.create_sandbox(spec).await {
            Ok(sandbox_id) => {
                // 启动沙箱
                if let Err(e) = self.sandbox_manager.start_sandbox(sandbox_id).await {
                    error!("沙箱启动失败: {}", e);
                    return Err(Status::internal(format!("沙箱启动失败: {}", e)));
                }

                let sandbox_info = SandboxInfo {
                    sandbox_id: sandbox_id.to_string(),
                    language: req.language,
                    state: SandboxState::Running as i32,
                    allocated_at: chrono::Utc::now().timestamp_millis(),
                    resources: Some(ResourceRequirements {
                        memory_mb: resources.memory_mb,
                        cpu_cores: resources.cpu_cores,
                        disk_mb: resources.disk_mb,
                        network_enabled: resources.network_enabled,
                    }),
                };

                info!("成功分配沙箱: {}", sandbox_id);
                Ok(Response::new(sandbox_info))
            }
            Err(e) => {
                error!("沙箱分配失败: {}", e);
                Err(Status::internal(format!("沙箱分配失败: {}", e)))
            }
        }
    }

    /// 执行代码
    async fn execute_code(
        &self,
        request: Request<ExecutionRequest>,
    ) -> Result<Response<ExecutionResult>, Status> {
        let req = request.into_inner();
        info!("收到代码执行请求: sandbox_id={}", req.sandbox_id);

        let sandbox_id = match req.sandbox_id.parse::<SandboxId>() {
            Ok(id) => id,
            Err(_) => {
                return Err(Status::invalid_argument("无效的沙箱ID格式"));
            }
        };

        // 转换语言类型
        let language = match Language::try_from(req.language) {
            Ok(lang) => convert_language_to_core(lang),
            Err(_) => {
                return Err(Status::invalid_argument("不支持的编程语言"));
            }
        };

        // 构建执行请求
        let exec_req = crate::types::ExecutionRequest {
            sandbox_id,
            source_code: req.source_code,
            language,
            entry_point: req.entry_point,
            dependencies: req.dependencies.into_iter().map(|dep| {
                crate::types::Dependency {
                    name: dep.name,
                    version: dep.version,
                    source: dep.source,
                }
            }).collect(),
            env_vars: req.env_vars,
            stdin: req.stdin,
            timeout_ms: Some(req.timeout_ms as u64),
        };

        // 执行代码
        match self.sandbox_manager.execute_code(sandbox_id, exec_req).await {
            Ok(result) => {
                let execution_result = ExecutionResult {
                    success: result.success,
                    stdout: result.stdout,
                    stderr: result.stderr,
                    exit_code: result.exit_code.unwrap_or(0),
                    execution_time_ms: result.execution_time_ms,
                    memory_usage_mb: result.memory_usage_mb,
                };

                info!("代码执行完成: sandbox_id={}, success={}", 
                      sandbox_id, result.success);
                Ok(Response::new(execution_result))
            }
            Err(e) => {
                error!("代码执行失败: sandbox_id={}, error={}", sandbox_id, e);
                Err(Status::internal(format!("代码执行失败: {}", e)))
            }
        }
    }

    /// 释放沙箱
    async fn release_sandbox(
        &self,
        request: Request<ReleaseSandboxRequest>,
    ) -> Result<Response<ReleaseResponse>, Status> {
        let req = request.into_inner();
        info!("收到沙箱释放请求: sandbox_id={}", req.sandbox_id);

        let sandbox_id = match req.sandbox_id.parse::<SandboxId>() {
            Ok(id) => id,
            Err(_) => {
                return Err(Status::invalid_argument("无效的沙箱ID格式"));
            }
        };

        match self.sandbox_manager.destroy_sandbox(sandbox_id).await {
            Ok(_) => {
                info!("成功释放沙箱: {}", sandbox_id);
                Ok(Response::new(ReleaseResponse {
                    success: true,
                    message: "沙箱已成功释放".to_string(),
                }))
            }
            Err(e) => {
                error!("沙箱释放失败: sandbox_id={}, error={}", sandbox_id, e);
                Ok(Response::new(ReleaseResponse {
                    success: false,
                    message: format!("释放失败: {}", e),
                }))
            }
        }
    }

    /// 获取沙箱状态
    async fn get_sandbox_status(
        &self,
        request: Request<SandboxStatusRequest>,
    ) -> Result<Response<SandboxStatus>, Status> {
        let req = request.into_inner();

        let sandbox_id = match req.sandbox_id.parse::<SandboxId>() {
            Ok(id) => id,
            Err(_) => {
                return Err(Status::invalid_argument("无效的沙箱ID格式"));
            }
        };

        match self.sandbox_manager.get_sandbox_status(sandbox_id) {
            Ok(sandbox) => {
                let state_proto = convert_core_state_to_proto(sandbox.state.clone()) as i32;
                let status = SandboxStatus {
                    sandbox_id: sandbox.id.to_string(),
                    state: state_proto,
                    uptime_ms: sandbox.uptime()
                        .map(|d| d.as_millis() as u64)
                        .unwrap_or(0),
                    usage_count: sandbox.usage_count as u32,
                    last_used_at: sandbox.last_used
                        .map(|t| t.duration_since(std::time::UNIX_EPOCH)
                             .unwrap_or(std::time::Duration::ZERO)
                             .as_millis() as i64)
                        .unwrap_or(0),
                    health: Some(HealthStatus {
                        level: HealthLevel::Healthy as i32, // 简化实现
                        message: "运行正常".to_string(),
                    }),
                };

                Ok(Response::new(status))
            }
            Err(_) => {
                Err(Status::not_found("沙箱未找到"))
            }
        }
    }

    /// 获取系统统计信息
    async fn get_system_stats(
        &self,
        _request: Request<SystemStatsRequest>,
    ) -> Result<Response<SystemStats>, Status> {
        let stats = self.sandbox_manager.get_system_stats();

        // 构建池统计信息 (简化实现)
        let pool_stats = PoolStats {
            hot_pool: Some(PoolInfo {
                total: 0,
                available: 0,
                in_use: 0,
            }),
            warm_pool: Some(PoolInfo {
                total: 0,
                available: 0,
                in_use: 0,
            }),
            cold_pool: Some(PoolInfo {
                total: 0,
                available: 0,
                in_use: 0,
            }),
        };

        // 语言分布统计 (简化实现)
        let mut language_distribution = HashMap::new();
        language_distribution.insert("python".to_string(), 0);
        language_distribution.insert("javascript".to_string(), 0);
        
        // 状态分布统计 (简化实现)
        let mut state_distribution = HashMap::new();
        state_distribution.insert("running".to_string(), 0);
        state_distribution.insert("stopped".to_string(), 0);

        let system_stats = SystemStats {
            total_sandboxes: stats.get("total_sandboxes")
                .and_then(|v| v.as_u64())
                .unwrap_or(0) as u32,
            active_sandboxes: stats.get("active_sandboxes")
                .and_then(|v| v.as_u64())
                .unwrap_or(0) as u32,
            pool_stats: Some(pool_stats),
            language_distribution,
            state_distribution,
            resource_usage: Some(ResourceUsage {
                cpu_usage_percent: 0.0,
                memory_usage_percent: 0.0,
                memory_used_mb: 0,
                memory_total_mb: 1024,
                active_connections: 0,
            }),
            timestamp: chrono::Utc::now().timestamp_millis(),
        };

        Ok(Response::new(system_stats))
    }

    /// 健康检查
    async fn health_check(
        &self,
        _request: Request<HealthCheckRequest>,
    ) -> Result<Response<HealthCheckResponse>, Status> {
        // 执行健康检查
        let health_check_result = self.sandbox_manager.perform_health_check().await;
        
        let mut details = HashMap::new();
        details.insert("version".to_string(), env!("CARGO_PKG_VERSION").to_string());
        
        let (status, uptime_ms) = match health_check_result {
            Ok(()) => {
                details.insert("status".to_string(), "healthy".to_string());
                (HealthLevel::Healthy as i32, 0i64) // 简化实现，实际可以计算真实运行时间
            }
            Err(e) => {
                details.insert("status".to_string(), "unhealthy".to_string());
                details.insert("error".to_string(), e.to_string());
                (HealthLevel::Unhealthy as i32, 0i64)
            }
        };

        let response = HealthCheckResponse {
            status,
            version: env!("CARGO_PKG_VERSION").to_string(),
            uptime_ms,
            details,
        };

        Ok(Response::new(response))
    }
}

// 类型转换辅助函数

fn convert_language_to_core(lang: Language) -> CoreLanguage {
    match lang {
        Language::Python => CoreLanguage::Python,
        Language::Javascript => CoreLanguage::JavaScript,
        Language::Java => CoreLanguage::Java,
        Language::Rust => CoreLanguage::Rust,
        Language::Go => CoreLanguage::Go,
        Language::Cpp => CoreLanguage::Cpp,
        Language::Unknown => CoreLanguage::Unknown,
    }
}

fn convert_core_language_to_proto(lang: CoreLanguage) -> Language {
    match lang {
        CoreLanguage::Python => Language::Python,
        CoreLanguage::JavaScript => Language::Javascript,
        CoreLanguage::Java => Language::Java,
        CoreLanguage::Rust => Language::Rust,
        CoreLanguage::Go => Language::Go,
        CoreLanguage::Cpp => Language::Cpp,
        CoreLanguage::Unknown => Language::Unknown,
    }
}

fn convert_priority_to_core(priority: Priority) -> CorePriority {
    match priority {
        Priority::Low => CorePriority::Low,
        Priority::Normal => CorePriority::Normal,
        Priority::High => CorePriority::High,
        Priority::Critical => CorePriority::Critical,
    }
}

fn convert_core_state_to_proto(state: crate::types::SandboxState) -> SandboxState {
    match state {
        crate::types::SandboxState::Creating => SandboxState::Creating,
        crate::types::SandboxState::Starting => SandboxState::Creating, // Map Starting to Creating
        crate::types::SandboxState::Running => SandboxState::Running,
        crate::types::SandboxState::Busy => SandboxState::Busy,
        crate::types::SandboxState::Stopping => SandboxState::Stopping,
        crate::types::SandboxState::Stopped => SandboxState::Stopped,
        crate::types::SandboxState::Error(_) => SandboxState::Error,
    }
}